﻿using MySystemSetup.IRole.Dto;
using MySystemSetup.IRolePremission;
using MySystemSetup.IRolePremission.Dto;
using MySystemSetup.IUser;
using MySystemSetup.RBACDomain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using TodoApp.Dto;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace MySystemSetup.RolePremission
{
    public class UserRolePremissionAppService : ApplicationService, IUserRolePremissionAppService
    {


        private readonly IRepository<Permission, string> _permissionRepository;
        private readonly IRepository<UserRole, int> _userRoleRepository;

        private readonly IRepository<RolePermission, int> _rolePermissionRepository;

        private readonly IRepository<RoleInfo, int> _roleRepository;

        public UserRolePremissionAppService(IRepository<Permission, string> permissionRepository, IRepository<UserRole, int> userRoleRepository, IRepository<RolePermission, int> rolePermissionRepository, IRepository<RoleInfo, int> roleRepository)
        {
            _permissionRepository = permissionRepository;
            _userRoleRepository = userRoleRepository;
            _rolePermissionRepository = rolePermissionRepository;
            _roleRepository = roleRepository;
        }



        /// <summary>
        /// 获取菜单列表
        /// </summary>
        /// <param name="uId">用户编号</param>
        /// <returns>菜单列表</returns>
        public List<UserRolePremissionDto> GetMenuList(string uId)
        {


            var perList = _permissionRepository.GetListAsync().Result;
            var rolePerList = _rolePermissionRepository.GetListAsync().Result;
            var userRoelList = _userRoleRepository.GetListAsync().Result;

            var query = from a in perList
                        join b in rolePerList
                        on a.Id equals b.PermissId
                        join c in userRoelList
                        on b.RoleId equals c.RoleId
                        where c.UId == uId
                        select a;

            var dirQuery = query.Distinct().ToList();




            return GetPerMission(dirQuery, "A");
        }


        /// <summary>
        /// 获取权限私有方法
        /// </summary>
        /// <param name="list">要查询的集合</param>
        /// <param name="parentId">父编号</param>
        /// <returns>菜单列表</returns>
        private List<UserRolePremissionDto> GetPerMission(IEnumerable<Permission> list, string parentId)
        {



            return list.Where(c => c.ParentId == parentId).Select(c => new UserRolePremissionDto
            {



                PerName = c.PerName,
                MenuUrl = c.MenuUrl,
                ParentId = c.ParentId,
                Children = GetPerMission(list, c.Id).Count() == 0 ? null : GetPerMission(list, c.Id)


            }).ToList();


        }


        /// <summary>
        /// 分页权限角色
        /// </summary>
        /// <param name="page">当前页</param>
        /// <param name="limit">页容量</param>
        /// <param name="rName">权限编号</param>
        /// <returns>统一返回格式</returns>

        public async Task<SzrApiPageResult<PerMissionRoleShowDto>> GetPerMissionRolePage(int page, int limit, string? number)
        {

            var perRes = await _permissionRepository.GetListAsync();
            var rolePerRes = await _rolePermissionRepository.GetListAsync();
            var roleRes = await _roleRepository.GetListAsync();



            var query = from a in roleRes
                        join b in rolePerRes
                        on a.Id equals b.RoleId
                        join c in perRes
                        on b.PermissId equals c.Id
                        select new PerMissionRoleShowDto()
                        {
                            Id = c.Id,
                            PerName = c.PerName,
                            ButtonPermiss = b.ButtonPermiss,
                            RoleName = a.RoleName,
                            RoleId = a.Id,
                        };

            query = query.WhereIf(number != null, x => x.Id == number);

            return new SzrApiPageResult<PerMissionRoleShowDto>()
            {
                code = 0,
                data = query.Skip((page - 1) * limit).Take(limit).ToList(),
                count = query.Count(),
                page = (int)Math.Ceiling(query.Count() * 1.0 / limit)
            };

        }



        /// <summary>
        /// 获取菜单列表
        /// </summary>
        /// <param name="uId">用户编号</param>
        /// <returns>菜单列表</returns>
        public List<TreeDto> GetMenuListTree()
        {


            var perList = _permissionRepository.GetListAsync().Result;
            var rolePerList = _rolePermissionRepository.GetListAsync().Result;
            var userRoelList = _userRoleRepository.GetListAsync().Result;

            var query = from a in perList
                        join b in rolePerList
                        on a.Id equals b.PermissId
                        join c in userRoelList
                        on b.RoleId equals c.RoleId

                        select a;

            var dirQuery = query.Distinct().ToList();




            return GetPerMissionTree(dirQuery, "A");
        }


        /// <summary>
        /// 获取权限私有方法
        /// </summary>
        /// <param name="list">要查询的集合</param>
        /// <param name="parentId">父编号</param>
        /// <returns>菜单列表</returns>
        private List<TreeDto> GetPerMissionTree(IEnumerable<Permission> list, string parentId)
        {



            return list.Where(c => c.ParentId == parentId).Select(c => new TreeDto
            {



                value = c.Id,
                label = c.PerName,
                disabled = false,
                children = GetPerMissionTree(list, c.Id).Count() == 0 ? null : GetPerMissionTree(list, c.Id)


            }).ToList();


        }



        /// <summary>
        /// 删除角色
        /// </summary>
        /// <param name="rId">角色编号</param>
        /// <returns>同意返回格式</returns>

        public async Task<SzrApiResult<RoleShowDto>> DeletePerMissAsync(string pId, int rId, string uId)
        {




            var perRes = await _rolePermissionRepository.GetListAsync(c => c.PermissId == pId && c.RoleId == rId);

            if
            (perRes.Count() > 0)
            {

                await _rolePermissionRepository.DeleteAsync(perRes.FirstOrDefault());


                //var res = await dbConnection.QueryAsync(

                //用户下的角色列表
                var userRoleList = await _userRoleRepository.GetListAsync(c => c.UId == uId);

                //角色列表(查询等级)
                var roleList = await _roleRepository.GetListAsync();


                //查询要删除的权限的角色等级
                var res = await _roleRepository.FindAsync(c => c.Id == rId);

                if (userRoleList.Count > 0 && roleList.Count > 0)
                {


                    //查到当当前用户下的最高等级角色
                    var query = roleList.Join(userRoleList, c => c.Id, c => c.RoleId,
                        (c, c1) => c).OrderBy(c => c.RoleGrade).First();

                    if (query.RoleGrade > res.RoleGrade || query.RoleGrade == res.RoleGrade)
                    {

                        return new SzrApiResult<RoleShowDto>()
                        {

                            code = 400,
                            msg = "添加的角色等级不能大于等于当前用户角色等级",


                        };

                    }
                }





                return new SzrApiResult<RoleShowDto>()
                {
                    code = 200,
                    msg = "删除成功"
                };
            }


            return new SzrApiResult<RoleShowDto>()
            {
                code = 400,
                msg = "删除失败"
            };



        }




        /// <summary>
        ///  更新角色权限
        /// </summary>
        /// <param name="list">要修改的集合</param>
        /// <returns>统一返回格式</returns>
        [UnitOfWork]
        public async Task<SzrApiResult<UpdRolePerDto>> UpdRolePerAsync(List<UpdRolePerDto> list)
        {

            //工作单元
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {


                try
                {

                    foreach (var item in list)
                    {



                        var rolePerRes = await _rolePermissionRepository.GetListAsync(c => c.RoleId == item.Id && c.PermissId == item.RoleGrade);

                        //用户下的角色列表
                        var userRoleList = await _userRoleRepository.GetListAsync(c => c.UId == item.RoleName);

                        //角色列表(查询等级)
                        var roleList = await _roleRepository.GetListAsync();


                        //查询要删除的权限的角色等级
                        var res = await _roleRepository.FindAsync(c => c.Id == item.Id);

                        if (userRoleList.Count > 0 && roleList.Count > 0)
                        {


                            //查到当当前用户下的最高等级角色
                            var query = roleList.Join(userRoleList, c => c.Id, c => c.RoleId,
                                (c, c1) => c).OrderBy(c => c.RoleGrade).First();

                            if (query.RoleGrade > res.RoleGrade || query.RoleGrade == res.RoleGrade)
                            {

                                return new SzrApiResult<UpdRolePerDto>()
                                {

                                    code = 400,
                                    msg = "修改权限的角色等级不能大于等于当前用户角色等级",


                                };

                            }
                        }

                        if (rolePerRes.Count() > 0)
                        {



                            rolePerRes.FirstOrDefault().ButtonPermiss = item.RoleDesc.TrimEnd(',');

                            await _rolePermissionRepository.UpdateAsync(rolePerRes.FirstOrDefault());
                        }
                        else
                        {

                            //查到当当前用户下的最高等级角色
                            var query = roleList.Join(userRoleList, c => c.Id, c => c.RoleId,
                                (c, c1) => c).OrderBy(c => c.RoleGrade).First();
                            if (query.RoleGrade > res.RoleGrade || query.RoleGrade == res.RoleGrade)
                            {

                                return new SzrApiResult<UpdRolePerDto>()
                                {

                                    code = 400,
                                    msg = "修改权限的角色等级不能大于等于当前用户角色等级",


                                };

                            }
                            //如果不存在，则新增
                            await _rolePermissionRepository.InsertAsync(new RolePermission()
                            {

                                RoleId = item.Id,
                                PermissId = item.RoleGrade,
                                ButtonPermiss = item.RoleDesc.TrimEnd(','),

                            });
                        }
                    }


                    //提交
                    await unitOfWork.CompleteAsync();


                    return new SzrApiResult<UpdRolePerDto>()
                    {
                        code = 200,
                        msg = "更新成功"
                    };
                }
                catch (Exception ex)
                {

                    // 如果发生异常，则回滚事务
                    unitOfWork.Dispose();

                    throw;
                }


            }
        }









    }
}
